#ifndef REGISTER_H
#define REGISTER_H

#include <stdlib.h>
#include <stdio.h>

#include "handler.h"
#include "patterns/singleton.h"

/* Тип используемого метода, при котором пришли данные */
enum METHODS {UNKNOW, GET_METHOD, POST_METHOD};


/*
 * Класс реестр handler'ов, он ответственен за добавление handler'а и вызова
 * подходящего
 */
class Register {
    public:
        // функция обработки и вызова функции подходящего хендлера с
        // подстановкой аргументов в функцию
        int start();

        // функция возвращающая тип метода
        static enum METHODS get_method_type() {
            static METHODS method = UNKNOW;
            char *val = NULL;

            if (method == UNKNOW) {
                if (
                    ((val = getenv("REQUEST_METHOD")) != NULL) &&
                    (*val == 'P')
                ) method = POST_METHOD;
                else method = GET_METHOD;
            }

            return method;
        }

        // Перегрузка оператора, добавляет handler в список хендлеров, если
        // хендлер привязан к типу метода, по которому придут данные
        // иначе ничего не добавляет
        Register &operator ,(enum METHODS method) {
            method == Register::get_method_type() ?
                    _append_state = 1 :
                    _append_state = 0;

            return *this;
        }

        // Добавление параметров
        Register &operator ,(const char *param) {
            if (_append_state) _tmp._params.push_back(param);

            return *this;
        }

        // Добавление функции для handler'а и помещение его в список хендлеров
        Register &operator ,(int (*f) (t_args *args)) {
            if (_append_state) {
                _tmp._func = f;
                _handlers.push_back(_tmp);
                _tmp._params.clear();
                _append_state = 0;
            }

            return *this;
    }

    private:
        Handler _tmp;              // временный хендлер для добавления в список
        vector<Handler> _handlers; // список хендлеров
        short _append_state;       // датчик состояния, отвечающий за
                                   // добавление хендлера
};

#define CGI_GET   Singleton<Register>::create(),GET_METHOD
#define CGI_POST  Singleton<Register>::create(),POST_METHOD
#define CGI_START Singleton<Register>::create().start()

#endif // REGISTER_H
